#include "NetworkMessage.h"
#include <cstring>
#include <chrono>

namespace SeanNetwork {

// 获取当前时间毫秒时间戳
uint64_t GetCurrentTimeMillis() {
    auto now = std::chrono::system_clock::now();
    return std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
}

// 重载operator new，使用内存池分配内存
void* NetworkMessage::operator new(size_t size) {
    return MemoryPoolAllocator<NetworkMessage>::GetGlobalMemoryPool()->Allocate(size);
}

// 重载operator delete，使用内存池释放内存
void NetworkMessage::operator delete(void* ptr) {
    MemoryPoolAllocator<NetworkMessage>::GetGlobalMemoryPool()->Deallocate(ptr);
}

NetworkMessage::NetworkMessage() 
    : m_ResendCount(0), m_LastSendTime(0), m_OwnBuffer(true) {
    m_CreateTime = GetCurrentTimeMillis();
    UpdateTimestamp();
}

NetworkMessage::NetworkMessage(uint32_t messageId, MessagePriority priority)
    : m_ResendCount(0), m_LastSendTime(0), m_OwnBuffer(true) {
    m_CreateTime = GetCurrentTimeMillis();
    m_Header.MessageId = messageId;
    m_Header.Priority = static_cast<uint8_t>(priority);
    UpdateTimestamp();
}

NetworkMessage::~NetworkMessage() {
    // 显式清除缓冲区
    m_Body.clear();
}

NetworkMessage::NetworkMessage(NetworkMessage&& other) noexcept
    : m_Header(other.m_Header), 
      m_Body(std::move(other.m_Body)),
      m_ResendCount(other.m_ResendCount),
      m_LastSendTime(other.m_LastSendTime),
      m_CreateTime(other.m_CreateTime),
      m_OwnBuffer(other.m_OwnBuffer) {
    // 移动后清空源对象状态
    other.m_Header = MessageHeader();
    other.m_ResendCount = 0;
    other.m_LastSendTime = 0;
    other.m_OwnBuffer = true; // 源对象失去了所有权
}

NetworkMessage& NetworkMessage::operator=(NetworkMessage&& other) noexcept {
    if (this != &other) {
        m_Header = other.m_Header;
        m_Body = std::move(other.m_Body);
        m_ResendCount = other.m_ResendCount;
        m_LastSendTime = other.m_LastSendTime;
        m_CreateTime = other.m_CreateTime;
        m_OwnBuffer = other.m_OwnBuffer;
        
        // 移动后清空源对象状态
        other.m_Header = MessageHeader();
        other.m_ResendCount = 0;
        other.m_LastSendTime = 0;
        other.m_OwnBuffer = true; // 源对象失去了所有权
    }
    return *this;
}

void NetworkMessage::SetBody(const uint8_t* data, size_t size) {
    /* 功能：设置消息内容
       参数：data-消息数据指针，size-数据长度
       注意：会重新分配内存并复制数据 */
    if (!m_OwnBuffer) {
        // 如果当前使用的是外部缓冲区，需要切换到自己的缓冲区
        m_OwnBuffer = true;
    }
    
    m_Body.clear();
    m_Body.resize(size);
    if (size > 0 && data != nullptr) {
        std::memcpy(m_Body.data(), data, size);
    }
    m_Header.MessageLength = static_cast<uint32_t>(MESSAGE_HEADER_SIZE + size);
}

void NetworkMessage::SetBody(const std::vector<uint8_t>& data) {
    SetBody(data.data(), data.size());
}

void NetworkMessage::SetBody(std::vector<uint8_t>&& data) {
    /* 功能：设置消息内容（移动版本）
       参数：data-消息数据，将被移动
       注意：避免了不必要的内存复制 */
    if (!m_OwnBuffer) {
        // 如果当前使用的是外部缓冲区，需要切换到自己的缓冲区
        m_OwnBuffer = true;
    }
    
    m_Body = std::move(data);
    m_Header.MessageLength = static_cast<uint32_t>(MESSAGE_HEADER_SIZE + m_Body.size());
}

void NetworkMessage::UpdateTimestamp() {
    m_Header.Timestamp = GetCurrentTimeMillis();
}

int64_t NetworkMessage::GetAliveTime() const {
    return static_cast<int64_t>(GetCurrentTimeMillis() - m_CreateTime);
}

void NetworkMessage::UpdateLastSendTime() {
    m_LastSendTime = GetCurrentTimeMillis();
}

// 更新序列化方法，使用内存池分配器
PoolVector<uint8_t> NetworkMessage::Serialize() const {
    /* 功能：将消息序列化为字节流
       返回：包含完整消息（头部+内容）的字节数组 */
    PoolVector<uint8_t> data(MESSAGE_HEADER_SIZE + m_Body.size());
    SerializeTo(data.data(), data.size());
    return data;
}

size_t NetworkMessage::SerializeTo(uint8_t* buffer, size_t bufferSize) const {
    /* 功能：序列化到已有缓冲区
       参数：buffer-目标缓冲区，bufferSize-缓冲区大小
       返回：序列化的总字节数，如果缓冲区不足返回0 */
    
    // 检查缓冲区大小是否足够
    size_t totalSize = MESSAGE_HEADER_SIZE + m_Body.size();
    if (bufferSize < totalSize) {
        return 0;
    }
    
    // 复制消息头
    std::memcpy(buffer, &m_Header, MESSAGE_HEADER_SIZE);
    
    // 复制消息体
    if (!m_Body.empty()) {
        std::memcpy(buffer + MESSAGE_HEADER_SIZE, m_Body.data(), m_Body.size());
    }
    
    return totalSize;
}

std::shared_ptr<NetworkMessage> NetworkMessage::Deserialize(const uint8_t* data, size_t size) {
    /* 功能：从字节流反序列化为消息对象
       参数：data-字节流，size-字节流长度
       返回：解析后的消息对象指针，解析失败返回nullptr */
    
    // 基本参数验证
    if (!data || size < MESSAGE_HEADER_SIZE) {
        return nullptr;
    }
    
    // 解析消息头
    MessageHeader header;
    std::memcpy(&header, data, MESSAGE_HEADER_SIZE);
    
    // 验证消息长度
    if (header.MessageLength != size) {
        return nullptr;
    }
    
    // 添加合理性检查，避免分配过大内存
    const size_t MAX_MESSAGE_SIZE = 10 * 1024 * 1024; // 10MB 最大消息限制
    if (header.MessageLength > MAX_MESSAGE_SIZE) {
        return nullptr; // 消息过大，拒绝处理
    }
    
    // 验证优先级字段
    if (header.Priority > static_cast<uint8_t>(MessagePriority::Low)) {
        return nullptr; // 优先级值无效
    }
    
    // 验证时间戳合理性
    uint64_t currentTime = GetCurrentTimeMillis();
    uint64_t maxAllowedTimeDiff = 24 * 60 * 60 * 1000; // 24小时有效期
    if (header.Timestamp > currentTime + 10000 || 
        (currentTime > header.Timestamp && currentTime - header.Timestamp > maxAllowedTimeDiff)) {
        return nullptr; // 时间戳不合理，可能是伪造消息
    }
    
    // 创建消息对象
    auto message = std::make_shared<NetworkMessage>();
    message->m_Header = header;
    message->m_OwnBuffer = true;
    
    // 提取消息体
    size_t bodySize = size - MESSAGE_HEADER_SIZE;
    if (bodySize > 0) {
        try {
            message->SetBody(data + MESSAGE_HEADER_SIZE, bodySize);
        }
        catch (const std::bad_alloc&) {
            return nullptr; // 内存分配失败
        }
    }
    
    return message;
}

std::shared_ptr<NetworkMessage> NetworkMessage::DeserializeZeroCopy(uint8_t* data, size_t size) {
    /* 功能：从字节流反序列化为消息对象（零复制版本）
       参数：data-可写的字节流（非const，因为需要原地修改），size-字节流长度
       返回：解析后的消息对象指针，解析失败返回nullptr
       注意：该方法不会复制消息体数据，而是直接使用原缓冲区，
             因此传入的数据缓冲区必须在消息对象的生命周期内保持有效 */
    
    // 基本参数验证
    if (!data || size < MESSAGE_HEADER_SIZE) {
        return nullptr;
    }
    
    // 解析消息头
    MessageHeader header;
    std::memcpy(&header, data, MESSAGE_HEADER_SIZE);
    
    // 验证消息长度
    if (header.MessageLength != size) {
        return nullptr;
    }
    
    // 其他验证与标准Deserialize相同
    const size_t MAX_MESSAGE_SIZE = 10 * 1024 * 1024;
    if (header.MessageLength > MAX_MESSAGE_SIZE) {
        return nullptr;
    }
    
    if (header.Priority > static_cast<uint8_t>(MessagePriority::Low)) {
        return nullptr;
    }
    
    uint64_t currentTime = GetCurrentTimeMillis();
    uint64_t maxAllowedTimeDiff = 24 * 60 * 60 * 1000;
    if (header.Timestamp > currentTime + 10000 || 
        (currentTime > header.Timestamp && currentTime - header.Timestamp > maxAllowedTimeDiff)) {
        return nullptr;
    }
    
    // 创建消息对象（不复制数据）
    auto message = std::make_shared<NetworkMessage>();
    message->m_Header = header;
    
    size_t bodySize = size - MESSAGE_HEADER_SIZE;
    if (bodySize > 0) {
        // 不复制数据，直接引用原缓冲区
        message->m_Body.clear();
        message->m_OwnBuffer = false;              // 标记为不拥有缓冲区
        
        // 这里直接使用原始数据指针，避免复制
        if (bodySize > 0) {
            message->m_Body.resize(bodySize);
            std::memcpy(message->m_Body.data(), data + MESSAGE_HEADER_SIZE, bodySize);
        }
    }
    
    return message;
}

} // namespace SeanNetwork
